package com.ksd.pug.cloud.rule;

import com.ksd.pug.cloud.rule.hash.ConsistentHashServer;
import com.ksd.pug.cloud.rule.hash.HashFunction;
import com.ksd.pug.cloud.rule.hash.Md5HashFunctionImpl;
import com.netflix.client.config.IClientConfig;
import com.netflix.loadbalancer.AbstractLoadBalancerRule;
import com.netflix.loadbalancer.IRule;
import com.netflix.loadbalancer.RoundRobinRule;
import com.netflix.loadbalancer.Server;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.util.List;

/**
 * @author 飞哥
 * @Title: 学相伴出品
 * @Description: 飞哥B站地址：https://space.bilibili.com/490711252
 * 记得关注和三连哦！
 * @Description: 我们有一个学习网站：https://www.kuangstudy.com
 * @date 2022/2/24 17:45
 */
public class MyHashRule extends AbstractLoadBalancerRule {

    private IRule subRule = new RoundRobinRule();

    public MyHashRule() {

    }

    public MyHashRule(IRule rule) {
        this.subRule = rule == null ? new RoundRobinRule() : rule;
    }

    @Override
    public void initWithNiwsConfig(IClientConfig clientConfig) {

    }

    @Override
    public Server choose(Object key) {
        // 1： 获取请求的上下文
        ServletRequestAttributes servletRequestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        HttpServletRequest request = servletRequestAttributes.getRequest();
        // 2: 获取服务列表
        List<Server> allServers = getLoadBalancer().getAllServers();
        // 3: 选择一个hash算法
        HashFunction hashFunction = new Md5HashFunctionImpl();
        // 4：一致性hash获取服务节点， 参数1：hashFunction  numberOfReplicas 100
        Long size = Double.valueOf(allServers.size() + allServers.size() * 0.5).longValue();
        ConsistentHashServer consistentHashServer = new ConsistentHashServer(hashFunction, size, allServers);
        System.out.println(consistentHashServer.circle.size());
        // 5: 访问key，key == url
        // 6: 访问key，key == url + ip
        // 7: 访问key，key == url + ip + Locale
        String uri = request.getServletPath() + "?" + request.getQueryString();
        Server server = consistentHashServer.get(uri);
        if (server == null) {
            server = subRule.choose(key);
        }
        return server;
    }


}